#include "stdafx.h"
#include "Framework\lego_3Dview.h"
#include "DLG_CubeAnalyzer.h"
#include "OpenGLControl.h"
#include "GLAddon\TrackBall.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

COpenGLControl::COpenGLControl()
{
	dc = NULL;
	fGLViewNear = -100.0;	fGLViewFar = 100.0; 	fGLViewHeight = 4.0;
	m_pTrackBall = NULL;
}

COpenGLControl::~COpenGLControl()
{
	if (dc)
	{
		delete dc;
	}
	SAFEDELETE(m_pTrackBall);
}


BEGIN_MESSAGE_MAP(COpenGLControl, CWnd)
	//{{AFX_MSG_MAP(COpenGLControl)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_CREATE()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void COpenGLControl::InitGL()
{
	glShadeModel(GL_SMOOTH);
	glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
	glClearDepth(1.0f);							
	//glEnable(GL_DEPTH_TEST);					
	glDepthFunc(GL_LEQUAL);	
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void COpenGLControl::DrawCube(float dBBoxHSize){
	glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT);
	glDisable(GL_LIGHTING);
	glColor3f(255.0f, 0.0f, 0.0f);

	glBegin(GL_LINE_LOOP);
		glVertex3F(dBBoxHSize, dBBoxHSize, dBBoxHSize);
		glVertex3F(-dBBoxHSize, dBBoxHSize, dBBoxHSize);
		glVertex3F(-dBBoxHSize, -dBBoxHSize, dBBoxHSize);
		glVertex3F(dBBoxHSize, -dBBoxHSize, dBBoxHSize);
	glEnd();

	glBegin(GL_LINE_LOOP);
		glVertex3F(dBBoxHSize, -dBBoxHSize, -dBBoxHSize);
		glVertex3F(dBBoxHSize, dBBoxHSize, -dBBoxHSize);
		glVertex3F(-dBBoxHSize, dBBoxHSize, -dBBoxHSize);
		glVertex3F(-dBBoxHSize, -dBBoxHSize, -dBBoxHSize);
	glEnd();

	glBegin(GL_LINES);
		glVertex3F(dBBoxHSize, dBBoxHSize, dBBoxHSize);
		glVertex3F(dBBoxHSize, dBBoxHSize, -dBBoxHSize);
		glVertex3F(-dBBoxHSize, dBBoxHSize, dBBoxHSize);
		glVertex3F(-dBBoxHSize, dBBoxHSize, -dBBoxHSize);
		glVertex3F(-dBBoxHSize, -dBBoxHSize, dBBoxHSize);
		glVertex3F(-dBBoxHSize, -dBBoxHSize, -dBBoxHSize);
		glVertex3F(dBBoxHSize, -dBBoxHSize, dBBoxHSize);
		glVertex3F(dBBoxHSize, -dBBoxHSize, -dBBoxHSize);
	glEnd();
	glPopAttrib();
}


void COpenGLControl::Create(CRect rect, CWnd *parent)
{
	CString className = AfxRegisterWndClass(
		CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
		NULL,
		(HBRUSH)GetStockObject(BLACK_BRUSH),
		NULL);

	CreateEx(
		0,
		className,
		"OpenGL",
		WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
		rect,
		parent,
		0);

}

void COpenGLControl::OnPaint() 
{
	openGLDevice.makeCurrent();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glPushMatrix();

	//glTranslated(X, 0, 0);
	m_pTrackBall->TBMatrix();
	glScalef(m_fZoom, m_fZoom, m_fZoom);		
	//glLoadIdentity();

	DrawCube(1);

	glPopMatrix();

	SwapBuffers(dc->m_hDC);
	glFinish();

	CWnd::OnPaint(); 
}

void COpenGLControl::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	GlWndSize.cx = cx;	GlWndSize.cy = cy;
	if (cy == 0)	cy = 1;						
	
	float dAspect = (float)cx / (float)((cy == 0) ? 1 : cy);
	fGLViewWidth = fGLViewHeight * dAspect;

// 	glViewport(0, 0, cx, cy);
// 	glMatrixMode(GL_PROJECTION);
// 	glLoadIdentity();
// 	glOrtho(-fGLViewWidth, fGLViewWidth, -fGLViewHeight, fGLViewHeight, fGLViewNear, fGLViewFar);
// 	glMatrixMode(GL_MODELVIEW);
// 	glLoadIdentity();
// 	glTranslatef(0.0, 0.0, -5.0);

	CSize size(cx, cy);
	double aspect;
	aspect = (cy == 0) ? (double)size.cx : (double)size.cx/(double)size.cy;
	glViewport(0, 0, size.cx, size.cy);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(25, aspect, 0.01, fGLViewFar);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -18.0);
	
	m_pTrackBall->ReSize(GlWndSize.cx,GlWndSize.cy);			

}


int COpenGLControl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	dc = new CClientDC(this);

	openGLDevice.create(dc->m_hDC);

	m_pTrackBall = new CTrackBall<double>((CWnd*)this, RealTimeEvent_Animation, ANIMATE_RATE);
	m_pTrackBall->Reset();
	m_pTrackBall->SetAnimate(FALSE);
	m_pTrackBall->m_bTracking = TRUE;
	m_fZoom = 1.0;
	InitGL();
	return 0;
}

BOOL COpenGLControl::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

CPoint LastPos;
void COpenGLControl::OnMouseMove( UINT nFlags, CPoint point )
{	
	if(GetAsyncKeyState(VK_LBUTTON)<0){  		
		m_pTrackBall->Motion(point.x, point.y);			
		InvalidateRect(NULL, FALSE);
	}
	else if(GetAsyncKeyState(VK_RBUTTON)<0){
		float offset = (point.y-LastPos.y)*0.06;
		m_fZoom += offset;
		if (m_fZoom < 0.0f)	m_fZoom = 0.0f;
		InvalidateRect(NULL, FALSE);
	}	
	LastPos = point;
	CWnd::OnMouseMove(nFlags, point);
}

void COpenGLControl::OnLButtonDown( UINT nFlags, CPoint point )
{
	m_pTrackBall->MouseDown(point.x, point.y);
}

void COpenGLControl::OnLButtonUp( UINT nFlags, CPoint point )
{
	m_pTrackBall->MouseUp();
}

